<template>
  <div class="app-container">
    <!-- 工具栏 -->
    <PageTools show-before>
      <span slot="before">共{{ total }}条记录</span>
      <template slot="after">
        <el-button size="small" type="warning" @click="exportData"
         v-power="'export'" >excel导出</el-button
        >
        <el-button size="small" type="success" @click="handleUploadExcel"
         v-power="'import'" >excel导入</el-button
        >
        <el-button size="small" type="primary" @click="handleAddEmployee"
        v-power="'add'"  >新增员工</el-button
        >
        <el-button size="small" type="danger" @click="handleBatchDelete"
        v-power="'delete'"  >批量删除</el-button
        >
      </template>
    </PageTools>
    <!-- 员工列表 -->
    <el-card>
      <LTable
        :tableData="tableData"
        :column="column"
        index
        checkbox
        @select="handleSelect"
        @select-all="handleSelect"
      >
        <!-- 头像 slot start -->
        <template v-slot:avatar="{ scope }">
          <img
            v-if="scope.staffPhoto"
            :src="scope.staffPhoto"
            alt=""
            class="avatar"
          />
          <img v-else src="../../assets/bg.svg" alt="" class="avatar" />
        </template>
        <!-- 头像 slot end -->
        <!-- 操作项 slot start -->
        <template v-slot:options="{ scope }">
          <el-button size="mini" @click="handelSee(scope)" type="text"
            >查看</el-button
          >
          <el-button
            size="mini"
            type="text"
            v-power="'assignRole'" 
            @click="handlerOpenAssignRoleDialog(scope)"
            >分配角色</el-button
          >
          <el-button size="mini" type="danger" v-power="'delete'" @click="handleDelete(scope)"
            >删除</el-button
          >
        </template>
        <!-- 操作项 slot end -->
      </LTable>
      <!-- 分页器 start -->
      <Pagination
        :total="total"
        bg
        class="page"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange"
      />
      <!-- 分页器 end -->
    </el-card>
    <!-- 新增员工弹窗 -->
    <add-employee
      ref="dialogRef"
      :showDialog.sync="showAddDialog"
      :treeData="department"
      @confirm="handleCreateEmployee"
    />
    <!-- 分配角色 -->
    <assign-role
      :showDialog.sync="showAssignRoleDialog"
      ref="assignRoleRef"
      :roleList="roleList"
      @confirm="handlerAssignRole"
    />
  </div>
</template>

<script>
import {
  getAllEmployeeAPI,
  createEmployeeAPI,
  deleteEmployeeAPI,
  getEmployeeBasicInfoAPI,
  assignEmployeeRoleAPI,
} from "@/api/employees"; //API
import { getAllRoleAPI } from "@/api/settings";
import { getCompanyDepartmentAPI } from "@/api/departments"; //API
import EmployeeEnum from "@/api/constant/employees"; // 引入枚举对象
import tranTree from "@/utils/format-to-tree"; //转树形格式
import msgTip from "@/utils/message-tip"; //消息提示
import formatDate from "@/utils/formatDate"; //时期格式化
import importAll from "@/utils/importAll";
const components = importAll(
  require.context("./components", false, /\.vue$/),
  ".vue"
);
export default {
  data() {
    return {
      column: Object.freeze([
        {
          prop: "username",
          label: "姓名",
          sort: true,
          toolstip: true,
          align: "center",
        },
        { label: "头像", slot: "avatar", align: "center" }, //solt 开启插槽
        {
          prop: "mobile",
          label: "手机号",
          sort: true, //开启排序
          method: (a, b) => {
            //前端本地排序
            return Number(a.mobile - b.mobile);
          },
          toolstip: true,
          align: "center",
        },
        {
          prop: "workNumber",
          label: "工号",
          sort: true,
          align: "center",
          method: (a, b) => {
            return Number(a.workNumber - b.workNumber);
          },
          toolstip: true,
        },
        {
          prop: "formOfEmployment",
          label: "聘用形式",
          sort: true,
          toolstip: true,
          align: "center",
          formatter: (row, column, cellValue, index) => {
            //格式化聘用形式 （1：正式 2：非正式）
            const obj = EmployeeEnum.hireType.find(
              (item) => item.id + "" === cellValue + ""
            );
            return obj ? obj.value : "未知";
          },
        },
        {
          prop: "departmentName",
          label: "部门",
          sort: true,
          toolstip: true,
          align: "center",
        },
        {
          prop: "timeOfEntry",
          align: "center",
          label: "入职时间",
          sort: true,
          method: (a, b) => {
            return Number(a.timeOfEntry - b.timeOfEntry);
          },
          formatter: (row, column, cellValue, index) => {
            return formatDate(cellValue);
          },
        },
        {
          label: "操作",
          slot: "options",
          width: 260,
          fixed: "right",
          align: "center",
        },
      ]), //对象冻结-该属性不需要响应式
      tableData: [], //角色信息列表
      total: 0, //员工
      query: {
        //所在页数（page） 每页显示条数(size)
        page: 1, //所在页数
        size: 10, //每页显示条数
      },
      showAddDialog: false, //新增员工Dialog 显示、隐藏标识符
      showAssignRoleDialog: false, //分配角色弹窗
      department: Object.freeze([]), //部门列表
      ids: Object.freeze([]), //批量删除员工id数据
      employeeId: "", //分配角色员工id
      roleList: [],
    };
  },
  created() {
    this.getAllEmployee(); //获取员工列表
    this.getCompanyDepartment(); //获取公司部门
  },
  components,
  methods: {
    // 查看员工详情
    handelSee({ id, formOfEmployment }) {
      this.$router.push({
        path: "/employees/detail",
        query: {
          id,
          employ: formOfEmployment,
        },
      });
    },
    //新增员工==显示Dialog
    handleAddEmployee() {
      this.showAddDialog = true;
    },
    //新增员工==网络请求
    async handleCreateEmployee(form) {
      const res = await createEmployeeAPI(form);
      msgTip({ msg: res.message });
      this.$refs.dialogRef.restForm();
    },
    //获取员工列表
    async getAllEmployee() {
      
      const {
        data: { total, rows },
      } = await getAllEmployeeAPI(this.query);

      this.tableData = rows;
      this.total = total;
    },
    //获取公司部门
    async getCompanyDepartment() {
      const { data } = await getCompanyDepartmentAPI();
      this.department = tranTree(data.depts); //扁平数据转树形数据
    },
    //分页页数改变
    handleCurrentChange(page) {
      this.query.page = page;
      this.getAllEmployee();
    },
    //页面条数改变
    handleSizeChange(size) {
      this.query.size = size;
      this.getAllEmployee();
    },
    //excel批量导入
    handleUploadExcel() {
      this.$router.push({
        path: "/employees/upload",
      });
    },
    // 导出excel
    exportData(isComplex) {
      // 懒加载 script-loader
      import("@/vendor/Export2Excel").then(async (excel) => {
        const {
          data: { rows },
        } = await getAllEmployeeAPI({
          page: 1,
          size: this.total,
        });
        // rows就是所有的数据 rows [{k:v,...,k:v},{},{}] => [[value,...,value],[],[],[]]
        const data = this.formatJson(EmployeeEnum.excel, rows); // 转化数据表结构
        excel.export_json_to_excel({
          header: Object.keys(EmployeeEnum.excel),
          data,
          filename: "员工用户表", // 非必填
          autoWidth: true, // 非必填
          bookType: "xlsx", // 非必填
        });
      });
    },
    //删除员工===单条
    async handleDelete(data) {
      this.$confirm(`删除${data.username}, 是否继续?`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          const res = await deleteEmployeeAPI(data.id);
          msgTip({ msg: res.message });
          if (this.tableData.length === 1) {
            this.query.page--;
          }
          this.getAllEmployee(); //刷新员工信息
        })
        .catch(() => {});
    },
    //选数据行的 Checkbox 时触发的事件
    handleSelect(selection) {
      this.ids = this.$options.data().ids; //重置数据
      selection.forEach((item) => {
        this.ids.push(item.id);
      });
    },
    //批量删除
    handleBatchDelete() {
      this.$confirm("删除选择数据, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          this.ids.forEach(async (item) => {
            const deleteLength = this.ids.length;
            await deleteEmployeeAPI(item);
            this.ids.splice(0, 1);
            if (this.ids.length !== 0) {
              return; //跳出本次循环
            }
            if (this.tableData.length === deleteLength) {
              this.query.page--;
            }
            this.getAllEmployee(); //刷新员工信息
          });
        })
        .catch(() => {});
    },
    //格式化员工列表数据
    formatJson(headers, rows) {
      return rows.map((item) => {
        return Object.values(headers).map((value) => {
          if (value === "formOfEmployment") {
            const obj = EmployeeEnum.hireType.find(
              (el) => el.id + "" === item[value] + ""
            );
            return obj ? obj.value : "未知";
          } else if (value === "timeOfEntry" || value === "correctionTime") {
            return formatDate(item[value]);
          }
          return item[value];
        });
      });
    },
    //打开分配角色弹窗
    async handlerOpenAssignRoleDialog({ id }) {
      if (this.roleList.length === 0) {
        this.getRoleList(); //获取角色
      }
      this.employeeId = id;
      await this.getEmployeeRloe();
      this.showAssignRoleDialog = true;
    },
    //分配角色
    async handlerAssignRole(params) {
      const data = { id: this.employeeId, ...params };
      const res = await assignEmployeeRoleAPI(data);
      this.$refs.assignRoleRef.closeDialog();
      msgTip({ msg: res.message });
    },
    // 获取员工角色
    async getEmployeeRloe() {
      return new Promise(async (resolve, reject) => {
        const {
          data: { roleIds },
        } = await getEmployeeBasicInfoAPI(this.employeeId);
        roleIds === null
          ? (this.$refs.assignRoleRef.roleIds = [])
          : (this.$refs.assignRoleRef.roleIds = roleIds);

        resolve();
      });
    },
    // 获取角色列表
    async getRoleList() {
      const { data } = await getAllRoleAPI();
      this.roleList = data.rows;
    },
  },
};
</script>

<style >
.page {
  margin-top: 10px;
}
.avatar {
  vertical-align: middle;
  width: 70px;
  height: 70px;
  border-radius: 50%;
}
</style>